﻿using System;
using System.Drawing;
using System.Collections.Generic; 
using System.Text;
using System.Windows.Forms;
 

namespace ICSharpCode.WinFormsUI.Controls
{
    public class NTextBox : Control
    {
        protected bool _foused = false;
        protected bool _passwordchar = false;
        protected XTextBox baseTextBox = null;
        protected Bitmap unlockIcon = null;

        protected Rectangle iconRection = Rectangle.Empty;

        protected Rectangle unlockRection = Rectangle.Empty;

        private BorderStyle _borderStyle;
        public BorderStyle BorderStyle
        {
            get { return _borderStyle; }
            set { _borderStyle = value; }
        }

        private Color _fousedColor;
        public Color FousedColor
        {
            get { return _fousedColor; }
            set { _fousedColor = value; }
        }

        private Bitmap _icon = null;
        public Bitmap Icon
        {
            get { return _icon; }
            set
            {
                _icon = value;
                if (_icon != null)
                {
                    this.baseTextBox.SetBounds(24, 6, this.ClientSize.Width - 30, 18, BoundsSpecified.All);
                }
                else
                {
                    this.baseTextBox.SetBounds(4, 6, this.ClientSize.Width - 8, 18, BoundsSpecified.All);
                }
                this.Invalidate();
            }
        }

        private IconLayout _iconLayout = IconLayout.Left;
        public IconLayout IconLayout
        {
            get { return _iconLayout; }
            set
            {
                _iconLayout = value;
                switch (_iconLayout)
                {
                    case IconLayout.Left:
                        this.baseTextBox.SetBounds(24, 6, this.ClientSize.Width - 30, this.ClientSize.Height - 8, BoundsSpecified.All);
                        break;
                    case IconLayout.Right:
                        this.baseTextBox.SetBounds(7, 6, this.ClientSize.Width - 30, this.ClientSize.Height - 8, BoundsSpecified.All);
                        break;
                }
                this.Invalidate();
            }
        }

        private Color tempColor = Color.Empty;

        private bool _enabled = true;
        public new bool Enabled
        {
            get { return _enabled; }
            set
            {
                _enabled = value;
                this.baseTextBox.Visible = _enabled;
                if (_enabled)
                {
                    if (tempColor != Color.Empty)
                    {
                        _xbackColor = tempColor;
                        baseTextBox.BackColor = _xbackColor;
                    }
                }
                else
                {                    
                    if (_xDisableColor != Color.Empty)
                    {                       
                        _xbackColor = XDisableColor;
                    }
                }
                this.Invalidate();
            }
        }

        public bool ReadOnly
        {
            get { return this.baseTextBox.ReadOnly; }
            set { this.baseTextBox.ReadOnly = value; }
        }

        private Color _xforeColor = SystemColors.ControlText;
        public Color XForeColor
        {
            get
            {                
                return _xforeColor;
            }
            set
            {
                _xforeColor = value;
                if (baseTextBox != null)
                {
                    baseTextBox.ForeColor = _xforeColor;
                    baseTextBox.TextForeColor = _xforeColor;
                }
                ForeColor = XForeColor;
            }
        }

        private Color _xbackColor = SystemColors.Window;
        public Color XBackColor
        {
            get
            {               
                return _xbackColor;
            }
            set
            {
                _xbackColor = value;
                if (baseTextBox != null)
                {
                    baseTextBox.BackColor = _xbackColor;
                }
                tempColor = Color.FromArgb(_xbackColor.R, _xbackColor.G, _xbackColor.B);
                BackColor = _xbackColor;
            }
        }

        private Color _xDisableColor = Color.Empty;
        public Color XDisableColor
        {
            get { return _xDisableColor; }
            set { _xDisableColor = value; }
        }

        public new string Text
        {
            get
            {
                if (baseTextBox == null)
                    return "";
                return baseTextBox.Text;
            }
            set
            {
                baseTextBox.Text = value;
                if (!string.IsNullOrEmpty(baseTextBox.Text)
                    && baseTextBox.Text != Placeholder)
                {
                    baseTextBox.ForeColor = XForeColor;
                }
            }
        }
               
        public string Placeholder
        {
            get { return this.baseTextBox.Placeholder; }
            set
            {
                this.baseTextBox.Placeholder = value;  
            }
        }          

        public bool Multiline
        {
            get { return baseTextBox.Multiline; }
            set { baseTextBox.Multiline = value; }
        }

        public int MaxLength
        {
            get { return this.baseTextBox.MaxLength; }
            set { this.baseTextBox.MaxLength = value; }
        }

        public char PasswordChar
        {
            get { return baseTextBox.PasswordChar; }
            set
            {
                baseTextBox.PasswordChar = value;
            }
        }

        public bool UseSystemPasswordChar
        {
            get { return baseTextBox.UseSystemPasswordChar; }
            set
            {
                baseTextBox.UseSystemPasswordChar = false;
            }
        }

        private bool _isPasswordTextBox = false;
        public bool IsPasswordTextBox
        {
            get { return _isPasswordTextBox; }
            set
            {
                _isPasswordTextBox = value;
                this.unlockIcon = Properties.Resources.openeye;
                this.RecalceSize();
                this.Invalidate();
            }
        }

        private bool _isClearTextBox = false;
        public bool IsClearTextBox
        {
            get { return _isClearTextBox; }
            set
            {
                _isClearTextBox = value;
                this.unlockIcon = Properties.Resources.delete;
                this.RecalceSize();
                this.Invalidate();
            }
        }

        private bool _isButtonTextBox = false;
        public bool IsButtonTextBox
        {
            get { return _isButtonTextBox; }
            set { _isButtonTextBox = value; }
        }

        public EventHandler UnlockSecret = null;

        private void RecalceSize()
        {
            if (this._icon != null)
            {
                switch (_iconLayout)
                {
                    case IconLayout.Left:
                        this.baseTextBox.SetBounds(24, 6, this.ClientSize.Width - 30, this.ClientSize.Height - 8, BoundsSpecified.All);
                        break;
                    case IconLayout.Right:
                        this.baseTextBox.SetBounds(7, 6, this.ClientSize.Width - 30, this.ClientSize.Height - 8, BoundsSpecified.All);
                        break;
                }
                if (this._isPasswordTextBox || this._isClearTextBox)
                {
                    this.baseTextBox.Size = new Size(this.baseTextBox.Width - 20, this.ClientSize.Height - 8);
                }
                unlockRection = new Rectangle(this.ClientSize.Width - 20, 4, 16, 16);
            }
            else
            {
                this.baseTextBox.SetBounds(4, 6, this.ClientSize.Width - 8, this.ClientSize.Height - 8, BoundsSpecified.All);
            } 
        }

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // NTextBox
            // 
            this.Name = "NTextBox";
            this.FousedColor = Color.Orange;
            this.Size = new System.Drawing.Size(150, 26);

            this.baseTextBox = new XTextBox();
            this.baseTextBox.Multiline = false;
            this.baseTextBox.BorderStyle = BorderStyle.None;           
            this.BorderStyle = BorderStyle.None;
            this.BackColor = Color.White;
            this.baseTextBox.BackColor = this.BackColor;
            this.unlockIcon = Properties.Resources.openeye;
            this.IsPasswordTextBox = false;
            this.IsClearTextBox = false;
            
            this.baseTextBox.SetBounds(4, 6, this.ClientSize.Width - 8, 18, BoundsSpecified.All);
            this.baseTextBox.GotFocus += new EventHandler(baseTextBox_GotFocus);
            this.baseTextBox.LostFocus += new EventHandler(baseTextBox_LostFocus);

            this.Controls.Add(this.baseTextBox);

            this.ResumeLayout(false);

        }

        private void baseTextBox_GotFocus(object sender, EventArgs e)
        {
            _foused = true;             
            this.Invalidate();
        }

        private void baseTextBox_LostFocus(object sender, EventArgs e)
        {
            _foused = false;
            this.Invalidate();
        }

        public NTextBox()
        {
            InitializeComponent();           
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Pen pen = new Pen(SystemColors.ControlDark);

            Graphics graphic = e.Graphics;

            graphic.FillRectangle(new SolidBrush(_xbackColor), new Rectangle(0, 0, Width, Height));

            if (this._foused)
            {
                if (this._enabled)
                    pen = new Pen(this.FousedColor);
            }

            if (this._icon != null)
            {
                switch (_iconLayout)
                {
                    case IconLayout.Left :
                        this.iconRection = new Rectangle(new Point(4, 4), new Size(16, 16));
                        break;
                    case IconLayout.Right:
                        this.iconRection = new Rectangle(new Point(this.ClientSize.Width - 20, 4), new Size(16, 16));
                        break;
                }
                graphic.DrawImage(this._icon, iconRection);

                if (!this._isClearTextBox && this._isPasswordTextBox)
                {
                    graphic.DrawImage(this.unlockIcon, this.unlockRection);
                }
                if (this._isClearTextBox && !this._isPasswordTextBox)
                {
                    graphic.DrawImage(this.unlockIcon, this.unlockRection);
                }

            }

            if (!_enabled && baseTextBox != null && !string.IsNullOrEmpty(baseTextBox.Text))
            {
                //StringFormat sf = new StringFormat() { Alignment = StringAlignment.Near, LineAlignment = StringAlignment.Center, FormatFlags = StringFormatFlags.DisplayFormatControl };
                //System.Windows.Forms.ControlPaint.DrawStringDisabled(graphic, baseTextBox.Text, baseTextBox.Font, _xforeColor,
                //   new Rectangle(2, 2, Width - 4, Height - 4), sf);
                TextRenderer.DrawText(graphic, baseTextBox.Text, baseTextBox.Font, new Point(2, 6), _xforeColor, TextFormatFlags.TextBoxControl | TextFormatFlags.SingleLine);
            }

            Rectangle clientRection = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
            graphic.DrawRectangle(pen, clientRection);
 
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            if (this.baseTextBox == null)
                return;
            RecalceSize();  
        }

        protected override void OnMouseClick(MouseEventArgs e)
        {
            base.OnMouseClick(e);

            if (this._isPasswordTextBox)
            {
                if (unlockRection.Contains(e.Location))
                {
                    if (!_passwordchar)
                    {
                        _passwordchar = true;
                        unlockIcon = (Bitmap)Properties.Resources.closeeye.Clone();
                    }
                    else
                    {
                        _passwordchar = false;
                        unlockIcon = (Bitmap)Properties.Resources.openeye.Clone();
                    }

                    this.baseTextBox.Focus();
                    this.Invalidate();

                    if (this.UnlockSecret != null)
                        this.UnlockSecret(this, new EventArgs());

                }
            }
            if (this._isClearTextBox)
            {
                if (unlockRection.Contains(e.Location))
                {
                    this.baseTextBox.Text = "";
                    this.baseTextBox.Focus();
                    this.Invalidate();

                    if (this.UnlockSecret != null)
                        this.UnlockSecret(this, new EventArgs());

                }
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            if (this.IsPasswordTextBox || this.IsClearTextBox || this.IsButtonTextBox )
            {
                if (this.unlockRection.Contains(e.Location))
                {
                    if (this.Cursor != Cursors.Hand)
                        this.Cursor = Cursors.Hand;
                }
                else
                {
                    if (this.Cursor != Cursors.Default)
                        this.Cursor = Cursors.Default;
                }
            }
        }

        public void ApplyStyles()
        {
            //baseTextBox.Focus();
            baseTextBox.Invalidate();
            this.Invalidate();           
        }

        public void AppendText(string text)
        {
            this.baseTextBox.AppendText(text);
        }
    }

    public class XTextBox : TextBox
    {
        private string _placeholder;
        public string Placeholder
        {
            get { return _placeholder; }
            set
            {
                _placeholder = value;

                if (string.IsNullOrEmpty(this.Text))
                {
                    base.Text = _placeholder;
                    this.ForeColor = Color.Gray;
                }

                this.Invalidate();
            }
        }

        private string _text;
        public new string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                base.Text = _text;
            }
        }

        private Color _placeholderColor = Color.Gray;

        private Color _textForeColor = Color.Black;

        internal Color TextForeColor
        {
            get { return _textForeColor; }
            set { _textForeColor = value; }
        }   

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            if (string.IsNullOrEmpty(_text) || _text.Equals(_placeholder))
                base.Text = "";
            this.ForeColor = _textForeColor;
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            if (!string.IsNullOrEmpty(_text))
            {
                base.Text = _text;
                this.ForeColor = _textForeColor;
            }
            else
            {
                base.Text = _placeholder;
                this.ForeColor = Color.Gray;
            }
        }        

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            _text = base.Text;
        }
       
    }
    
    public enum IconLayout{
        Left,
        Right
    }

   
}
